﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ripple.Providers;
using Ripple.Data;
using System.Collections.Generic;
using System.Linq;

namespace Ripple.Test
{
    [TestClass]
    public class RippleContextUnitTest
    {
        [TestMethod]
        public void AccountsProperty()
        {
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);

            Assert.IsNotNull(ripple.Accounts);
        }

        [TestMethod]
        public void ConstructorInjectedProvider()
        {
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);

            Assert.IsNotNull(ripple);
            Assert.IsInstanceOfType(ripple.Provider, typeof(IRippleProvider));
        }

        [TestMethod]
        public void ConstructorUsingAppConfig()
        {
            RippleContext ripple = new RippleContext();

            Assert.IsNotNull(ripple);
            Assert.IsInstanceOfType(ripple.Provider, typeof(IRippleProvider));
        }

        [TestMethod]
        public void GetAccountCached()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);

            // Act
            Account result1 = ripple.Accounts.Get("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59");
            Account result2 = ripple.Accounts.Get("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59");

            // Assert
            Assert.AreSame(result1, result2);
        }

        [TestMethod]
        public void GetAccountFound()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);

            // Act
            Account result = ripple.Accounts.Get("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59");

            // Assert
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void GetAccountNotFound()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);

            // Act
            Account result = ripple.Accounts.Get("unittest");

            // Assert
            Assert.IsNull(result);
        }

        [TestMethod]
        public void GetOffersSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);
            string accountId = "rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM";

            // Act
            IEnumerable<Offer> result = ripple.Offers.Get(accountId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreNotEqual(0, result.Count());
            foreach (Offer entity in result)
            {
                Assert.AreEqual(accountId, entity.AccountId);
            }
        }

        [TestMethod]
        public void GetTransationsForAccountSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);
            string accountId = "rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM";

            // Act
            IEnumerable<Transaction> result = ripple.Transactions.GetForAccount(accountId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreNotEqual(0, result.Count());
        }

        [TestMethod]
        public void GetTrustLinesForPeerNotFound()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);

            // Act
            IEnumerable<TrustLine> result = ripple.TrustLines.Get("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", "unknownpeer");

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count());
        }

        [TestMethod]
        public void GetTrustLinesForPeerSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);
            string accountId = "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59";
            string peerAccountId = "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z";

            // Act
            IEnumerable<TrustLine> result = ripple.TrustLines.Get(accountId, peerAccountId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreNotEqual(0, result.Count());
            foreach (TrustLine line in result)
            {
                Assert.AreEqual(accountId, line.AccountId);
                Assert.AreEqual(peerAccountId, line.PeerAccountId);
                Assert.IsNotNull(line.Currency);
            }
        }

        [TestMethod]
        public void GetTrustLinesSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);
            Assert.IsNotNull(ripple.Accounts);
            string accountId = "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59";

            // Act
            IEnumerable<TrustLine> result = ripple.TrustLines.Get(accountId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreNotEqual(0, result.Count());
            foreach (TrustLine line in result)
            {
                Assert.AreEqual(accountId, line.AccountId);
                Assert.IsNotNull(line.Currency);
            }
        }

        [TestMethod]
        public void TrustLinesProperty()
        {
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            RippleContext ripple = new RippleContext(provider);

            Assert.IsNotNull(ripple.TrustLines);
        }
    }
}